<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/3/15
 * Time: 9:27
 */

namespace app\common\lib;


use support\Cache;
use Webman\Http\UploadFile;

class TencentCos
{
    public $secretid;

    public $secretkey;

    public $bucket;

    public $region;

    public $cosClient;

    public $filePathNames;

    protected static $instance;

    public function __construct()
    {
        $config = config('param.tencent_cloud');
        $this->secretid = $config['secretid'];
        $this->secretkey = $config['secretkey'];
        $this->region = $config['cos']['region'];
        $this->bucket = $config['cos']['bucket'];

        $this->cosClient = new \Qcloud\Cos\Client(
            [
                'region' => $this->region,
                'scheme' => 'https', //协议头部，默认为http
                'credentials'=> [
                    'secretId'  => $this->secretid ,
                    'secretKey' => $this->secretkey
                ]
            ]
        );
    }

    public static function getInstance()
    {
        //        if(is_object(self::$instance)){
//            return self::$instance;
//        }


        return new self();
    }

    public function asyncUploadFile($filePath,$uniKey,$dirPath='',$name='')
    {
        $filePathNames = $this->setFilePathAndName($filePath,$dirPath,$name);
        try {
            $data = [
                'progress'=>0,
                'url'=>'',
                'msg'=>'uploading',
            ];
            Cache::set('uploadfile_progress_'.$uniKey,$data,300);

            $result = $this->cosClient->upload(
                 $this->bucket, //存储桶名称，由BucketName-Appid 组成，可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
                $filePathNames['savepath'], //此处的 key 为对象键
                fopen($filePath, 'rb'),
                [
                    'Progress'=>function($totalSize,$uploadedSize) use(&$uniKey){
                        $progress = round($uploadedSize/$totalSize*100);
                        $data = [
                            'progress'=>$progress,
                            'url'=>'',
                            'msg'=>'uploading',
                        ];
                        Cache::set('uploadfile_progress_'.$uniKey,$data,300);
                    }
                ]
            );
            // 请求成功
            //print_r($result);
            $data = [
                'progress'=>100,
                'url'=> 'https://'.($result->toArray()['Location']),
                'msg'=>'success',
            ];
            Cache::set('uploadfile_progress_'.$uniKey,$data,300);

            return $result->toArray();
        } catch (\Exception $e) {
            // 请求失败
            $data = [
                'progress'=>-1,
                'url'=> '',
                'msg'=> $e->getMessage(),
            ];
            Cache::set('uploadfile_progress_'.$uniKey,$data,300);

            return ['status'=>'-1','msg'=>$e->getMessage()];
        }
    }

    public function uploadLocalFile($filePath,$dirPath='',$name='')
    {
        $filePathNames = $this->setFilePathAndName($filePath,$dirPath,$name);
        try {
            $result = $this->cosClient->upload(
                 $this->bucket, //存储桶名称，由BucketName-Appid 组成，可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
                $filePathNames['savepath'], //此处的 key 为对象键
                fopen($filePath, 'rb')

            );
            // 请求成功
            //print_r($result);
            return $result->toArray();
        } catch (\Exception $e) {
            // 请求失败
            throw $e;
        }
    }

    public function uploadStringFile($filePath,$dirPath='',$name='')
    {
        $filePathNames = $this->setFilePathAndName($filePath,$dirPath,$name);
        try {
            $result = $this->cosClient->upload(
                 $this->bucket, //存储桶名称，由BucketName-Appid 组成，可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
                $filePathNames['savepath'], //此处的 key 为对象键
                fopen($filePath, 'rb')

            );
            // 请求成功
            //print_r($result);
            return $result->toArray();
        } catch (\Exception $e) {
            // 请求失败
            throw $e;
        }
    }

    public function uploadFormFile(UploadFile $uploadFile,$dirPath='',$name='')
    {
        $filePathNames = $this->setFilePathAndName($uploadFile,$dirPath,$name);

        try {
            $result = $this->cosClient->upload(
                $bucket = $this->bucket, //存储桶名称，由BucketName-Appid 组成，可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
                $key = $filePathNames['savepath'], //此处的 key 为对象键
                $body = fopen($uploadFile->getRealPath(), 'rb')
            );
            // 请求成功
            //print_r($result);
            return $result->toArray();
        } catch (\Exception $e) {
            // 请求失败
            throw $e;
        }
    }

    public function setFilePathAndName($filePath, $dirPath='',$name='')
    {
        //时间
        $date = date('Ymd');

        //文件后缀名和文件名
        if($filePath instanceof UploadFile){
            //这个主要针对本地上传文件
            $fileName = $filePath->getUploadName();
            $mimeType = $filePath->getUploadMimeType();
            $extName = explode('/',$mimeType)[1];

            if($mimeType=='multipart/form-data' || $mimeType=='application/octet-stream'
                || $mimeType=='application/vnd.android.package-archive'
                || $mimeType=='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'){
                $extName = $filePath->getUploadExtension();
            }else{
                $mimeType=='audio/mpeg' && $extName = 'mp3';
                $mimeType=='video/mpeg' && $extName ='mp4';
                $extName=='quicktime' && $extName = 'mp4';
            }

            $fromfile = $fileName;
        }elseif(strpos($filePath,'http://')!==false || strpos($filePath,'https://')!==false){
            $path = parse_url($filePath,PHP_URL_PATH);
            if(strpos($path,'.')!==false){
                $fixAarr = explode('.',$path);
                $extName = $fixAarr[count($fixAarr)-1];

                $fileArr = explode('/',$path);
                $fileName = $fileArr[count($fileArr)-1];

                $fromfile = $filePath;
            }else{
                $extName = 'png';
                $fileName = (int) microtime(true)*10000;
                $fromfile = $filePath;
            }

        }elseif(file_exists($filePath)){
            $pathInfo = pathinfo($filePath);
            $extName = $pathInfo['extension'];
            $fileName = $pathInfo['basename'];

            $fromfile = $filePath;
        }else{
            $extName = 'png';
            $fileName = (int) microtime(true)*10000;
            $fromfile = $filePath;
        }

        $extName = $extName=='jpeg'? 'jpg': $extName;


        $savePath = config('app.app_name','video').'/';
        $savePath .= config('app.app_env','local').'/';
        $savePath .= $dirPath ? $dirPath .'/' : '';

        $saveFileName = $name ? $name : substr(md5($fileName.uniqid()),-20).'.'.$extName;
        if($name){
            $savePath .= $extName.'/'.$saveFileName;
        }else{
            $savePath .= $date .'/'.$extName.'/'.$saveFileName;
        }

        $this->filePathNames = [
            'savepath'=>$savePath,
            'savefilename'=>$saveFileName,
            'fixname'=>$extName,
            'upload_module'=>$dirPath,
            'fromfile'=>$fromfile,
        ];
        return $this->filePathNames ;
    }

    public function getBucketListObject($prefix,$marker='')
    {
        try {
            $result = $this->cosClient->listObjects(array(
                'Bucket' => $this->bucket, //存储桶名称，由BucketName-Appid 组成，可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
                'Delimiter' => '', //Delimiter表示分隔符, 设置为/表示列出当前目录下的object, 设置为空表示列出所有的object
                'EncodingType' => 'url',//编码格式，对应请求中的 encoding-type 参数
                'Marker' => $marker??'',//起始对象键标记
                'Prefix' => $prefix, //Prefix表示列出的object的key以prefix开始
                'MaxKeys' =>1000, // 设置最大遍历出多少个对象, 一次listObjects最大支持1000
            ));

            // 请求成功
            //print_r($result);
            return $result->toArray();
        } catch (\Throwable $e) {
            // 请求失败
           throw $e;
        }

    }

    public function deleteBucketObject($key)
    {

        try {
            $result = $this->cosClient->deleteObject(array(
                'Bucket' => $this->bucket, //存储桶名称，由BucketName-Appid 组成，可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
                'Key' => $key,
            ));
            // 请求成功
            return $result->toArray();
        } catch (\Exception $e) {
            // 请求失败
            throw $e;
        }

    }
}